
#include "mpi.h"
#include <cassert>
#include <iostream>

using namespace std;

int main(int argc, char **argv) {

  int global_rank, global_num_proc;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &global_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &global_num_proc);

  int *val, flag;
  MPI_Comm peer_comm;
  MPI_Comm_dup(MPI_COMM_WORLD, &peer_comm);

  MPI_Comm_get_attr(peer_comm, MPI_APPNUM, &val, &flag);

  MPI_Comm group_comm;
  MPI_Comm_split(MPI_COMM_WORLD, *val, global_rank, &group_comm);

  int group_rank, group_num_proc;
  MPI_Comm_rank(group_comm, &group_rank);
  MPI_Comm_size(group_comm, &group_num_proc);

  int leader_global_rank_send[2]{-1, -1};
  int leader_global_rank_recv[2]{-1, -1};
  if (group_rank == 0) {
    cout << "APPNUM: " << *val << "  leader_global_rank = " << global_rank
         << endl;
    leader_global_rank_send[*val] = global_rank;
  }

  MPI_Allreduce(leader_global_rank_send, leader_global_rank_recv, 2, MPI_INT,
                MPI_MAX, MPI_COMM_WORLD);

  if (group_rank == group_num_proc - 1) {
    cout << "  leader_global_rank[0] = " << leader_global_rank_recv[0] << "\n "
         << "leader_global_rank[1] =  " << leader_global_rank_recv[1] << endl;
  }

  int local_leader = 0;
  int remote_leader;
  if (*val == 0) {
    remote_leader = leader_global_rank_recv[1];
  } else {
    remote_leader = leader_global_rank_recv[0];
  }

  int tag = 9;
  MPI_Comm inter_comm;
  // if (*val == 0) {
  MPI_Intercomm_create(group_comm, 0, MPI_COMM_WORLD, remote_leader, tag,
                       &inter_comm);
  // } else {
  //   MPI_Intercomm_create(group_comm, 0, MPI_COMM_WORLD, remote_leader, tag,
  //                        &inter_comm);
  // }

  int remote_group_size = global_num_proc - group_num_proc;
  int data[2];
  for (int i = 0; i < 2; ++i)
    data[i] = group_rank;

  // cout << "hello3" << endl;
  // 只发送数据,不接收数据
  MPI_Allgather(data, 2, MPI_INT, nullptr, 0, MPI_INT, inter_comm);

  MPI_Finalize();
  return 0;
}